#-*- coding:utf-8 -*-
'''
Created on Oct 6, 2010

@author: Peter
'''
from numpy import *
import matplotlib
import matplotlib.pyplot as plt
from matplotlib.patches import Rectangle
import logRegres

#随机梯度上升法：每次循环中的第一次迭代都去第1个样本，第二次迭代取第2个样本。。。
#样本是有顺序的选择的
def stocGradAscent0(dataMatrix, classLabels,numiter=200):
    m,n = shape(dataMatrix)
    alpha = 0.1 #0.5
    weights = ones(n)   #initialize to all ones
    weightsHistory=zeros((numiter*m,n))
    #迭代次数
    for j in range(numiter):
        for i in range(m):
            h = logRegres.sigmoid(sum(dataMatrix[i]*weights))
            error = classLabels[i] - h
            weights = weights + alpha * error * dataMatrix[i]
            weightsHistory[j*m + i,:] = weights
    print weights #迭代结束最终参数更新结果
    return weightsHistory #每次迭代的参数值


#改进的随机梯度下降法：样本的顺序是随机的，并且alpha也是逐渐减小的
def stocGradAscent1(dataMatrix, classLabels,numiter=200):
    m,n = shape(dataMatrix)
    weights = ones(n)   #initialize to all ones
    weightsHistory=zeros((numiter*m,n))
    for j in range(numiter):
        dataIndex = range(m)
        for i in range(m):
            #alpha也是逐渐减小的
            alpha = 4/(1.0+j+i)+0.01
            #每次迭代更新参数，随机选择某个样本
            randIndex = int(random.uniform(0,len(dataIndex)))
            h = logRegres.sigmoid(sum(dataMatrix[randIndex]*weights))
            error = classLabels[randIndex] - h
            #print error
            weights = weights + alpha * error * dataMatrix[randIndex]
            weightsHistory[j*m + i,:] = weights
            del(dataIndex[randIndex])
    print weights
    return weightsHistory




def drawWeights(weightsHistory):
    #一幅图中绘制三个子图，对应三个参数的变化情况
    ax1=plt.subplot(311)
    plt.sca(ax1)
    plt.plot(weightsHistory[:,0])
    plt.ylabel('X0')

    ax2=plt.subplot(312)
    plt.sca(ax2)
    plt.plot(weightsHistory[:,1])
    plt.ylabel('X1')

    ax3=plt.subplot(313)
    plt.sca(ax3)
    plt.plot(weightsHistory[:,2])
    plt.ylabel('X2')

    plt.xlabel('iteration')

    
if __name__=="__main__":
    #list类型数据
    dataMat,labelMat=logRegres.loadDataSet()
    #
    dataArr = array(dataMat)
    #随机梯度上升法：样本顺序选
    weightsHistory = stocGradAscent0(dataArr,labelMat)
    print'weightsHistory=',weightsHistory
    #随机梯度上升法改进1：样本随机选,alpha逐渐减小
    weightsHistory1 = stocGradAscent1(dataArr,labelMat)
    print'weightsHistory1=',weightsHistory1


    #用两个图分别绘制两种方法的对应的三个参数的变化趋势
    fig1=plt.figure(1)
    drawWeights(weightsHistory)
    fig2=plt.figure(2)
    drawWeights(weightsHistory1)

    plt.show()


